<script lang="ts" setup>
import { useUserStoreHook } from '@/stores/modules/user'
import type { SpCropperFile, SpCropperOption } from '@/components/SpCropper/type'
import { uploadFileAPI } from '@/api/file'
import { message } from 'ant-design-vue'
import type { Rule } from 'ant-design-vue/lib/form'
import dayjs from 'dayjs'
import type { SysUserEditType } from '@/views/admin/system/user/utils/model'
import { updateUserInfo, updateUserPassword } from '@/views/admin/system/user/utils/api'

const userStore = useUserStoreHook()

const userInfo = userStore.getUser

const themeToken = getThemeTokenHook()

/**
 * 截图配置
 */
const cropOption = reactive<SpCropperOption>({
  img: useUserStoreHook().getUserAvatar(),
  autoCropWidth: '200',
  autoCropHeight: '200',
  boxHeight: 300,
  boxWidth: 350,
  fixedBox: true
})
// 打开截图弹窗
const openShow = ref(false)
// 上传图片
const handleSubmit = (data: SpCropperFile): Promise<void> => {
  const formData: FormData = new FormData()
  if (data.file) {
    formData.append('file', data.file, data.fileName)
  }
  return new Promise((resolve, reject) => {
    uploadFileAPI(formData).then(async (res) => {
      resolve()
      // 更新用户头像
      await updateUserInfo({ phone: userInfo.phone, name: userInfo.name, avatar: res.data.fileUrl })
      userStore.updateUserAvatar(res.data.fileUrl)
      message.success('上传成功')
    })
  })
}

// loading
const userFormLoading = ref(false)
const userFormPasswordLoading = ref(false)
// 用户修改资料表单数据
const userForm = reactive(<SysUserEditType>{
  name: userInfo.name as string,
  phone: userInfo.phone as string,
  birthday: dayjs(userInfo.birthday, 'YYYY-MM-DD') as string,
  sex: 1
})
// 修改密码表单数据
const userEditPassword = reactive({
  newPassword: '',
  confirmPassword: ''
})

// 用户修改资料表单验证规则
const userFormRules: Record<string, Rule[]> = {
  name: [{ required: true, message: '请输入用户名称', trigger: 'blur' }],
  phone: [{ required: true, message: '请输入手机号码', trigger: 'blur' }]
}
// 确认密码验证规则
const validatePass = async (_rule: Rule, value: string) => {
  if (value !== userEditPassword.newPassword) {
    return Promise.reject('确认密码和新密码不一致')
  } else {
    return Promise.resolve()
  }
}

// 用户修改密码表单验证规则
const userPasswordFormRules: Record<string, Rule[]> = {
  newPassword: [{ required: true, message: '请输入新密码', trigger: 'blur' }],
  confirmPassword: [
    { required: true, message: '请输入确认密码', trigger: 'blur' },
    { validator: validatePass, trigger: 'blur' }
  ]
}

// 用户修改资料表单提交
const userFormFinish = (res: SysUserEditType) => {
  userFormLoading.value = true
  if (res.birthday != '') {
    res.birthday = dayjs(userForm.birthday).format('YYYY-MM-DD')
  }
  updateUserInfo(res)
    .then(() => {
      message.success('修改成功')
      userStore.updateUser(res)
    })
    .finally(() => {
      userFormLoading.value = false
    })
}

// 修改密码表单提交
const userPasswordFinish = () => {
  userFormPasswordLoading.value = true
  updateUserPassword(userEditPassword)
    .then(() => {
      message.success('修改成功')
    })
    .finally(() => {
      userFormPasswordLoading.value = false
    })
}

// 修改头像
const editAvatar = () => {
  openShow.value = true
  cropOption.img = 'tx_3.jpg'
}
</script>

<template>
  <div class="user-info">
    <SpCropper v-model="openShow" :before-submit="handleSubmit" v-bind="cropOption" />
    <a-row :gutter="20">
      <a-col :lg="8" :xs="24">
        <a-card title="个人信息">
          <div class="avatar">
            <div class="avatar-content">
              <img :src="useUserStoreHook().getUserAvatar()" alt="" />
              <div class="edit_avatar" @click="editAvatar">
                <Icon type="icon-edit" />
              </div>
            </div>
          </div>
          <div class="user-list">
            <div class="info-item">
              <div class="left">
                <Icon type="icon-user" />
                <span class="name">用户名称</span>
              </div>
              <div class="right">{{ userInfo.username }}</div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-phone" />
                <span class="name">手机号码</span>
              </div>
              <div class="right">{{ userInfo.phone }}</div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-wechat-fill" />
                <span class="name">微信ID</span>
              </div>
              <div class="right">{{ userInfo.openId }}</div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-apartment" />
                <span class="name">所属部门</span>
              </div>
              <div class="right">{{ userInfo.deptName }}</div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-team" />
                <span class="name">所属角色</span>
              </div>
              <div class="right">
                <a-tag v-for="item in userInfo.roles" :key="item.id" color="blue">{{
                  item.name
                }}</a-tag>
              </div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-idcard" />
                <span class="name">所属岗位</span>
              </div>
              <div class="right">
                <a-tag v-for="item in userInfo.posts" :key="item.id" color="cyan">{{
                  item.postName
                }}</a-tag>
              </div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-home" />
                <span class="name">归属地</span>
              </div>
              <div class="right">
                {{ userInfo.ipCity }}
              </div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-earth" />
                <span class="name">最后登录IP</span>
              </div>
              <div class="right">
                {{ userInfo.loginIp }}
              </div>
            </div>
            <div class="info-item">
              <div class="left">
                <Icon type="icon-time-circle" />
                <span class="name">最后登录时间</span>
              </div>
              <div class="right">
                {{ userInfo.loginDate }}
              </div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :lg="16" :xs="24">
        <a-card title="基本资料">
          <a-tabs>
            <a-tab-pane key="1" tab="用户资料">
              <a-form
                :rules="userFormRules"
                :model="userForm"
                :label-col="{ style: { width: '80px' } }"
                labelAlign="left"
                @finish="userFormFinish"
              >
                <a-form-item label="用户名称" name="name">
                  <a-input v-model:value="userForm.name" placeholder="请输入用户名称" type="text" />
                </a-form-item>
                <a-form-item label="手机号码" name="phone">
                  <a-input
                    v-model:value="userForm.phone"
                    placeholder="请输入用户手机号码"
                    type="text"
                  />
                </a-form-item>
                <a-form-item label="生日" name="birthday">
                  <a-date-picker
                    v-model:value="userForm.birthday"
                    style="width: 100%"
                    placeholder="请选择生日"
                  />
                </a-form-item>
                <a-form-item label="性别" name="sex">
                  <SpDict dict-type="user_sex" v-model="userForm.sex" type="radio" />
                </a-form-item>
                <a-form-item>
                  <div style="display: flex; justify-content: flex-end">
                    <a-button :loading="userFormLoading" type="primary" html-type="submit"
                      >保存</a-button
                    >
                  </div>
                </a-form-item>
              </a-form>
            </a-tab-pane>
            <a-tab-pane key="2" tab="修改密码" force-render>
              <a-form
                :rules="userPasswordFormRules"
                :model="userEditPassword"
                :label-col="{ style: { width: '80px' } }"
                labelAlign="left"
                @finish="userPasswordFinish"
              >
                <a-form-item label="新密码" name="newPassword">
                  <a-input-password
                    v-model:value="userEditPassword.newPassword"
                    placeholder="请输入用户新密码"
                  />
                </a-form-item>
                <a-form-item label="确认密码" name="confirmPassword">
                  <a-input-password
                    v-model:value="userEditPassword.confirmPassword"
                    placeholder="请确认新密码"
                    type="text"
                  />
                </a-form-item>
                <a-form-item>
                  <div style="display: flex; justify-content: flex-end">
                    <a-button :loading="userFormPasswordLoading" type="primary" html-type="submit"
                      >修改</a-button
                    >
                  </div>
                </a-form-item>
              </a-form>
            </a-tab-pane>
          </a-tabs>
        </a-card>
      </a-col>
    </a-row>
  </div>
</template>

<style scoped>
:deep(.ant-card-body) {
  padding-top: 0 !important;
}
.avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  padding-top: 15px;
  cursor: pointer;
  .avatar-content {
    position: relative;
    img {
      width: 100px;
      height: 100px;
      border-radius: 50%;
      object-fit: cover;
    }
    .edit_avatar {
      top: 0;
      position: absolute;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100px;
      height: 100px;
      border-radius: 50%;
      background: rgba(0, 0, 0, 0.5);
      opacity: 0;
      transition: opacity 0.3s;
      color: #fff;
    }
    &:hover {
      .edit_avatar {
        opacity: 1;
      }
    }
  }
}
.user-list {
  .info-item {
    display: flex;
    justify-content: space-between;
    font-size: 14px;
    padding-bottom: 10px;
    margin-bottom: 15px;
    border-bottom: 1px solid v-bind(themeToken.colorBorderSecondary);
    .left {
      .name {
        margin-left: 5px;
      }
    }
    &:last-child {
      border-bottom: none;
      margin-bottom: 0;
    }
  }
}
</style>
